package dhy.com.quarz;

import dhy.com.doamin.QuartzBean;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import us.codecraft.webmagic.Spider;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;


public class QuartzUtils {

    /**
     * 创建定时任务 定时任务创建之后默认启动状态
     * @param scheduler 调度器
     * @param quartzBean 定时任务信息类
     */
    @SuppressWarnings("unchecked")
    public static void createScheduleJob(Scheduler scheduler, QuartzBean quartzBean) throws ClassNotFoundException, SchedulerException {
            //获取到定时任务的执行类 必须是类的绝对路径名称
            //定时任务类需要是job类的具体实现 QuartzJobBean是job的抽象类。
            Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(quartzBean.getJobClass());
            // 构建定时任务信息
            JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(quartzBean.getJobName()).build();
            // 设置定时任务执行方式
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(quartzBean.getCronExpression());
            // 构建触发器trigger
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(quartzBean.getJobName()).withSchedule(scheduleBuilder).startNow().build();
            scheduler.scheduleJob(jobDetail, trigger);
    }


    /**
     * 创建定时任务 定时任务创建之后默认启动状态,携带参数
     * @param scheduler 调度器
     * @param quartzBean 定时任务信息类
     */
    @SuppressWarnings("unchecked")
    public static void createScheduleJobWithParams(Scheduler scheduler, QuartzBean quartzBean, JobDataMap params) throws ClassNotFoundException, SchedulerException {
        //获取到定时任务的执行类 必须是类的绝对路径名称
        //定时任务类需要是job类的具体实现 QuartzJobBean是job的抽象类。
        Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(quartzBean.getJobClass());
        // 构建定时任务信息
        JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(quartzBean.getJobName()).setJobData(params).build();
        // 设置定时任务执行方式
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(quartzBean.getCronExpression());
        // 构建触发器trigger
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(quartzBean.getJobName()).withSchedule(scheduleBuilder).startNow().build();
        scheduler.scheduleJob(jobDetail, trigger);
    }

    /**
     * 根据任务名称暂停定时任务
     * @param scheduler 调度器
     * @param jobName 定时任务名称
     */
    public static void pauseScheduleJob(Scheduler scheduler, String jobName) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(jobName);
        scheduler.pauseJob(jobKey);
    }

    /**
     * 根据任务名称恢复定时任务
     * @param scheduler 调度器
     * @param jobName 定时任务名称
     */
    public static void resumeScheduleJob(Scheduler scheduler, String jobName) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(jobName);
        scheduler.resumeJob(jobKey);
    }

    /**
     * 根据任务名称立即运行一次定时任务
     * @param scheduler 调度器
     * @param jobName 定时任务名称
     */
    public static void runOnce(Scheduler scheduler, String jobName) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(jobName);
        scheduler.triggerJob(jobKey);
    }

    /**
     * 更新定时任务
     * @param scheduler 调度器
     * @param quartzBean 定时任务信息类
     */
    public static void updateScheduleJob(Scheduler scheduler, QuartzBean quartzBean) throws SchedulerException {

            //获取到对应任务的触发器
            TriggerKey triggerKey = TriggerKey.triggerKey(quartzBean.getJobName());
            //设置定时任务执行方式
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(quartzBean.getCronExpression());
            //重新构建任务的触发器trigger
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
            //重置对应的job
            scheduler.rescheduleJob(triggerKey, trigger);
    }

    /**
     * 根据定时任务名称从调度器当中删除定时任务
     * @param scheduler 调度器
     * @param jobName 定时任务名称
     */
    public static void deleteScheduleJob(Scheduler scheduler, String jobName) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(jobName);
        scheduler.deleteJob(jobKey);
    }

    /**
     * 获取正在运行的job,进入休息间隔和停止爬取的不包括
     * @param scheduler 调度器
     */
    public static List<String> getAliveClawerList(Scheduler scheduler)
    {
        List<String> list = new LinkedList();
        try {
            //获取正在运行的所有JOB
            List<JobExecutionContext> currentlyExecutingJobs = scheduler.getCurrentlyExecutingJobs();
            for (JobExecutionContext executingJob : currentlyExecutingJobs)
            {
                  list.add(executingJob.getJobDetail().getKey().getName());
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 获取所有的job,包括进入休息间隔和停止爬取的
     * @param scheduler 调度器
     */
    public static List<String> getClawerList(Scheduler scheduler)
    {
        List<String> res=new LinkedList<>();
        GroupMatcher<JobKey> groupMatcher = GroupMatcher.anyJobGroup();
        try {
            Set<JobKey> jobKeys = scheduler.getJobKeys(groupMatcher);
            jobKeys.forEach(x->{
                res.add(x.getName());
            });
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return res;
    }

    /**
     * 获取当前用户开启的爬虫线程
     * @param scheduler 调度器
     * @param jobName 任务名字
     */
    public static List<JobDetail> getUserClawerList(Scheduler scheduler, String... jobName)
    {
        List<JobDetail> res=new LinkedList<>();
        try {
            for (String s : jobName) {
                JobDetail jobDetail = scheduler.getJobDetail(new JobKey(s));
                //当前爬虫线程存在
                if(jobDetail!=null)
                {
                    res.add(jobDetail);
                }
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return res;
    }
}
